package thinker.miracle.datasource;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;

import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;

public class DynamicDataSource extends AbstractRoutingDataSource {

	private Object master;  
	
    private List<Object> slave;  
    
    private int slaveSize = 0;  
  
    private AtomicInteger slaveIndex = new AtomicInteger(0);  
  
    /** 
     * 数据源键名 
     */  
    private static final String DATASOURCE_KEY_MASTER = "master";  
    
    private static final String DATASOURCE_KEY_SLAVE = "slave";  
  
    /* (non-Javadoc) 
     * @see org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource#afterPropertiesSet() 
     */  
    @Override  
    public void afterPropertiesSet() {  
        if (this.master == null) {  
            throw new IllegalArgumentException("Property 'master' is required");  
        }  
        setDefaultTargetDataSource(master);  
        Map<Object, Object> targetDataSources = new HashMap<>();  
        targetDataSources.put(DATASOURCE_KEY_MASTER, master);
        if (this.slave == null) {  
        	slaveSize = 0;  
        } else {  
            for(int i=0; i<slave.size(); i++) {  
                targetDataSources.put(DATASOURCE_KEY_SLAVE + i, slave.get(i));  
            }  
            slaveSize = slave.size();  
        }  
        setTargetDataSources(targetDataSources);  
        super.afterPropertiesSet();  
    }  
  
    /* (non-Javadoc)
     * @see org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource#determineCurrentLookupKey()
     */
    @Override  
    protected Object determineCurrentLookupKey() {  
        if(DynamicDataSourceHolder.isChoiceNone() || DynamicDataSourceHolder.isChoiceMaster() || slaveSize == 0) {  
            return DATASOURCE_KEY_MASTER;  
        }  
        int index = slaveIndex.incrementAndGet() % slaveSize;  
        return DATASOURCE_KEY_SLAVE + index;  
    }

    
    //get,set method
	public Object getMaster() {
		return master;
	}

	public void setMaster(Object master) {
		this.master = master;
	}

	public List<Object> getSlave() {
		return slave;
	}

	public void setSlave(List<Object> slave) {
		this.slave = slave;
	}  
}
